package org.atlantis.ymer.server.transport;

import java.util.List;
import java.util.Map;

import org.atlantis.ymer.WebSession;
import org.atlantis.ymer.common.HttpResponseUtils;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.http.HttpMethod;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.QueryStringDecoder;
import org.jboss.netty.util.CharsetUtil;

public abstract class HttpTransport extends AbstractTransport {

	@Override
	public void handle(ChannelHandlerContext ctx, Object data) {
		HttpRequest request = (HttpRequest) data;
		HttpMethod method = request.getMethod();
		if (method == HttpMethod.GET) {
			RequestParameter param = new RequestParameter(new QueryStringDecoder(request.getUri()).getParameters());
			handleGetMethod(ctx, request, param);
		} else if (method == HttpMethod.POST) {
			RequestParameter param = new RequestParameter(new QueryStringDecoder(request.getContent().toString(
					CharsetUtil.UTF_8), false).getParameters());
			handlePostMethod(ctx, request, param);
		} else if (method == HttpMethod.OPTIONS) { // client ask to Cross Domain
			HttpResponse crossDomainResponse = HttpResponseUtils.createCrossDomainHeaderResponse();
			crossDomainResponse.addHeader(HttpResponseUtils.CROSS_DOMAIN_METHOD, "POST, GET, OPTIONS");
			crossDomainResponse.addHeader(HttpResponseUtils.CROSS_DOMAIN_HEADER, "Content-Type");
			ctx.getChannel().write(crossDomainResponse).addListener(ChannelFutureListener.CLOSE);
		} else throw new IllegalArgumentException("Unsupport http method: " + method.getName());
	}

	protected WebSession tryGetWebSession(ChannelHandlerContext ctx, String webSessionId) {
		WebSession webSession = tryGetWebSession(webSessionId);
		if (webSession == null) ctx.getChannel().close();
		return webSession;
	}

	protected abstract void handleGetMethod(ChannelHandlerContext ctx, HttpRequest request, RequestParameter param);

	protected abstract void handlePostMethod(ChannelHandlerContext ctx, HttpRequest request, RequestParameter param);

	protected class RequestParameter {

		private Map<String, List<String>> parameters;

		private RequestParameter(Map<String, List<String>> parameters) {
			this.parameters = parameters;
		}

		String getWebSessionId() {
			List<String> sids = parameters.get("sid");
			if (sids == null || sids.size() <= 0) return null;
			return sids.get(0);
		}

		String getContent() {
			List<String> datas = parameters.get("content");
			if (datas == null || datas.size() <= 0) return null;
			return datas.get(0);
		}

		String getString(String name) {
			List<String> others = parameters.get(name);
			if (others == null || others.size() <= 0) return null;
			return others.get(0);
		}
	}
}
